<?php
/**
 * php GEM Project
 * 
 * LICENSE
 * 
 * PHP System Architecture Enabling Rapid Application Deployment and Scalability
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * @copyright Copyright (C) 2010 Zeletron LLC (http://zeletron.com)
 * @license http://gem.zeletron.com/license
 */

/**
 * GEM/Validate/Url.php
 * 
 * @author David Joly
 * @category GEM
 * @package GEM_Validate
 */

class GEM_Validate_Url extends Zend_Validate_Abstract 
{ 
	/**
	 * Validation failure message keys.
	 */
	const INVALID_URL = 'invalidUrl'; 
    const INVALID_HOSTNAME = 'invalidHostname';
	/**
     * Validation failure message template definition
     *
     * @var array
     */
	protected $_messageTemplates = array(
			self::INVALID_URL 		=> 'Invalid Url.',
			self::INVALID_HOSTNAME 	=> 'Invalid hostname.'
		); 
	
	/**
	 * The url scheme
	 * @var string
	 */
	protected $_scheme;
	
	/** 
	 * Constructor 
	 * 
	 * @param $scheme
	 * */
	public function __construct($scheme = 'http')
	{
		$this->_scheme = $scheme;
	}
	
    /**
     * Zend_Validate_Hostname fails if a url contains anything
     * after the TLD, including directory path and queries. 
     * @see Zend_Validate_Hostname::isValid()
     * 
     * Zend_Uri_Http properly validates a uri but throws an exception 
     * if no schema/protocol is present, nor does it validate the TLD. 
     * @see Zend_Uri_Http
     * 
     * @param $value 
     * @return boolean
     * @uses Zend_Uri_Http
     * @uses Zend_Validate_Hostname
     */
	public function isValid($value) 
	{ 
		if(preg_match('/.*:\/\//',$value) == 1){
			//Scheme detected...
			if(!preg_match('/http:\/\//',$value) == 1){
				//Valid Scheme not used...
				$this->_error(self::INVALID_URL);
				return false;
			}
			$urlValue = $value;
		} else {
			//No Scheme found. Append scheme...
			$urlValue = $this->_scheme . "://$value"; 
		}
		try {
			$url = Zend_Uri_Http::fromString($urlValue);
		} catch (Exception $e) { 
			//Multiple exceptions may be thrown by Zend_Uri_Validate,
			//catching any here by catching top level Exception class.
			Zend_Registry::get('logger')->log($urlValue,Zend_Log::DEBUG);
			$this->_error(self::INVALID_URL);
			return false;
		}
		//Url valid, validate hostname, allowing only DNS.
		$hostname = $url->getHost();
		$hostnameValidator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS);
		if(!$hostnameValidator->isValid($hostname)){
			$this->_error(self::INVALID_HOSTNAME);
			return false;
		}
		return true;
	} 
	
	
} 
